<!DOCTYPE html><html lang="en"><head>
  <meta charset="utf-8">
  <meta name="generator" content="ReSpec 32.1.8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <style>
  dfn{cursor:pointer}
  .dfn-panel{position:absolute;z-index:35;min-width:300px;max-width:500px;padding:.5em .75em;margin-top:.6em;font-family:"Helvetica Neue",sans-serif;font-size:small;background:#fff;color:#000;box-shadow:0 1em 3em -.4em rgba(0,0,0,.3),0 0 1px 1px rgba(0,0,0,.05);border-radius:2px}
  .dfn-panel:not(.docked)>.caret{position:absolute;top:-9px}
  .dfn-panel:not(.docked)>.caret::after,.dfn-panel:not(.docked)>.caret::before{content:"";position:absolute;border:10px solid transparent;border-top:0;border-bottom:10px solid #fff;top:0}
  .dfn-panel:not(.docked)>.caret::before{border-bottom:9px solid #a2a9b1}
  .dfn-panel *{margin:0}
  .dfn-panel b{display:block;color:#000;margin-top:.25em}
  .dfn-panel ul a[href]{color:#333}
  .dfn-panel>div{display:flex}
  .dfn-panel a.self-link{font-weight:700;margin-right:auto}
  .dfn-panel .marker{padding:.1em;margin-left:.5em;border-radius:.2em;text-align:center;white-space:nowrap;font-size:90%;color:#040b1c}
  .dfn-panel .marker.dfn-exported{background:#d1edfd;box-shadow:0 0 0 .125em #1ca5f940}
  .dfn-panel .marker.idl-block{background:#8ccbf2;box-shadow:0 0 0 .125em #0670b161}
  .dfn-panel a:not(:hover){text-decoration:none!important;border-bottom:none!important}
  .dfn-panel a[href]:hover{border-bottom-width:1px}
  .dfn-panel ul{padding:0}
  .dfn-panel li{margin-left:1em}
  .dfn-panel.docked{position:fixed;left:.5em;top:unset;bottom:2em;margin:0 auto;max-width:calc(100vw - .75em * 2 - .5em - .2em * 2);max-height:30vh;overflow:auto}
  </style>


  <title>Design Tokens Technical Reports</title>

  <meta name="color-scheme" content="light dark">

  <style id="respec-mainstyle">
  @keyframes pop{
  0%{transform:scale(1,1)}
  25%{transform:scale(1.25,1.25);opacity:.75}
  100%{transform:scale(1,1)}
  }
  :is(h1,h2,h3,h4,h5,h6,a) abbr{border:none}
  dfn{font-weight:700}
  a.internalDFN{color:inherit;border-bottom:1px solid #99c;text-decoration:none}
  a.externalDFN{color:inherit;border-bottom:1px dotted #ccc;text-decoration:none}
  a.bibref{text-decoration:none}
  .respec-offending-element:target{animation:pop .25s ease-in-out 0s 1}
  .respec-offending-element,a[href].respec-offending-element{text-decoration:red wavy underline}
  @supports not (text-decoration:red wavy underline){
  .respec-offending-element:not(pre){display:inline-block}
  .respec-offending-element{background:url() bottom repeat-x}
  }
  #references :target{background:#eaf3ff;animation:pop .4s ease-in-out 0s 1}
  cite .bibref{font-style:normal}
  code{color:#c63501}
  th code{color:inherit}
  a[href].orcid{padding-left:4px;padding-right:4px}
  a[href].orcid>svg{margin-bottom:-2px}
  .toc a,.tof a{text-decoration:none}
  a .figno,a .secno{color:#000}
  ol.tof,ul.tof{list-style:none outside none}
  .caption{margin-top:.5em;font-style:italic}
  table.simple{border-spacing:0;border-collapse:collapse;border-bottom:3px solid #005a9c}
  .simple th{background:#005a9c;color:#fff;padding:3px 5px;text-align:left}
  .simple th a{color:#fff;padding:3px 5px;text-align:left}
  .simple th[scope=row]{background:inherit;color:inherit;border-top:1px solid #ddd}
  .simple td{padding:3px 10px;border-top:1px solid #ddd}
  .simple tr:nth-child(even){background:#f0f6ff}
  .section dd>p:first-child{margin-top:0}
  .section dd>p:last-child{margin-bottom:0}
  .section dd{margin-bottom:1em}
  .section dl.attrs dd,.section dl.eldef dd{margin-bottom:0}
  #issue-summary>ul{column-count:2}
  #issue-summary li{list-style:none;display:inline-block}
  details.respec-tests-details{margin-left:1em;display:inline-block;vertical-align:top}
  details.respec-tests-details>*{padding-right:2em}
  details.respec-tests-details[open]{z-index:999999;position:absolute;border:thin solid #cad3e2;border-radius:.3em;background-color:#fff;padding-bottom:.5em}
  details.respec-tests-details[open]>summary{border-bottom:thin solid #cad3e2;padding-left:1em;margin-bottom:1em;line-height:2em}
  details.respec-tests-details>ul{width:100%;margin-top:-.3em}
  details.respec-tests-details>li{padding-left:1em}
  .self-link:hover{opacity:1;text-decoration:none;background-color:transparent}
  aside.example .marker>a.self-link{color:inherit}
  .header-wrapper{display:flex;align-items:baseline}
  :is(h2,h3,h4,h5,h6):not(#toc>h2,#abstract>h2,#sotd>h2,.head>h2){position:relative;left:-.5em}
  :is(h2,h3,h4,h5,h6):not(#toch2)+a.self-link{color:inherit;order:-1;position:relative;left:-1.1em;font-size:1rem;opacity:.5}
  :is(h2,h3,h4,h5,h6)+a.self-link::before{content:"§";text-decoration:none;color:var(--heading-text)}
  :is(h2,h3)+a.self-link{top:-.2em}
  :is(h4,h5,h6)+a.self-link::before{color:#000}
  @media (max-width:767px){
  dd{margin-left:0}
  }
  @media print{
  .removeOnSave{display:none}
  }
  </style>
  <meta name="description" content="Design tokens are indivisible pieces of a design system such as colors,
          spacing, typography scale.">
  <style>
  var:hover{text-decoration:underline;cursor:pointer}
  var.respec-hl{color:var(--color,#000);background-color:var(--bg-color);box-shadow:0 0 0 2px var(--bg-color)}
  @media (prefers-color-scheme:dark){
  var.respec-hl{filter:saturate(.9) brightness(.9)}
  }
  var.respec-hl-c1{--bg-color:#f4d200}
  var.respec-hl-c2{--bg-color:#ff87a2}
  var.respec-hl-c3{--bg-color:#96e885}
  var.respec-hl-c4{--bg-color:#3eeed2}
  var.respec-hl-c5{--bg-color:#eacfb6}
  var.respec-hl-c6{--bg-color:#82ddff}
  var.respec-hl-c7{--bg-color:#ffbcf2}
  @media print{
  var.respec-hl{background:0 0;color:#000;box-shadow:unset}
  }
  </style>
  <style>
  var{position:relative;cursor:pointer}
  var[data-type]::after,var[data-type]::before{position:absolute;left:50%;top:-6px;opacity:0;transition:opacity .4s;pointer-events:none}
  var[data-type]::before{content:"";transform:translateX(-50%);border-width:4px 6px 0 6px;border-style:solid;border-color:transparent;border-top-color:#000}
  var[data-type]::after{content:attr(data-type);transform:translateX(-50%) translateY(-100%);background:#000;text-align:center;font-family:"Dank Mono","Fira Code",monospace;font-style:normal;padding:6px;border-radius:3px;color:#daca88;text-indent:0;font-weight:400}
  var[data-type]:hover::after,var[data-type]:hover::before{opacity:1}
  </style>
  <script id="initialUserConfig" type="application/json">{
    "specStatus": "base",
    "thisVersion": "https://designtokens.org/TR/first-editors-draft/",
    "latestVersion": "https://www.designtokens.org/TR/third-editors-draft/",
    "edDraftURI": null,
    "publishDate": "2021-09-23",
    "subtitle": "First Editors’ Draft",
    "group": "design-tokens",
    "editors": [
      {
        "name": "Adekunle Oduye"
      },
      {
        "name": "Ayesha Mazumdar"
      },
      {
        "name": "Donna Vitan"
      },
      {
        "name": "James Nash"
      },
      {
        "name": "Johan Stromqvist"
      },
      {
        "name": "Kathleen McMahon"
      },
      {
        "name": "Kevin Powell"
      },
      {
        "name": "Louis Chenais"
      },
      {
        "name": "Matt Felten"
      },
      {
        "name": "Val Head"
      }
    ],
    "github": {
      "repoURL": "https://github.com/design-tokens/community-group",
      "branch": "first-editors-draft"
    },
    "tocIntroductory": true,
    "publishISODate": "2021-09-23T00:00:00.000Z",
    "generatedSubtitle": "Draft Community Group Report 23 September 2021"
  }</script>
  <link rel="stylesheet" href="https://www.w3.org/StyleSheets/TR/2021/cg-draft">
  <link rel="stylesheet" media="(prefers-color-scheme: dark)" href="https://www.w3.org/StyleSheets/TR/2021/dark.css"></head>
    <body class="h-entry informative"><div class="head">

      <h1 id="title" class="title">Design Tokens Technical Reports</h1> <h2 id="subtitle" class="subtitle">First Editors’ Draft</h2>
      <p id="w3c-state">
        <a href="https://www.w3.org/standards/types#reports">Draft Community Group Report</a>
        <time class="dt-published" datetime="2021-09-23">23 September 2021</time>
      </p>
      <dl>
        <dt>This version:</dt><dd>
                <a class="u-url" href="https://www.designtokens.org/TR/first-editors-draft/">https://www.designtokens.org/TR/first-editors-draft/</a>
              </dd>
        <dt>Latest published version:</dt><dd>
                <a href="https://www.designtokens.org/TR/third-editors-draft/">https://www.designtokens.org/TR/third-editors-draft/</a>
              </dd>





        <dt>Editors:</dt><dd class="editor p-author h-card vcard">
      <span class="p-name fn">Adekunle Oduye</span>
    </dd><dd class="editor p-author h-card vcard">
      <span class="p-name fn">Ayesha Mazumdar</span>
    </dd><dd class="editor p-author h-card vcard">
      <span class="p-name fn">Donna Vitan</span>
    </dd><dd class="editor p-author h-card vcard">
      <span class="p-name fn">James Nash</span>
    </dd><dd class="editor p-author h-card vcard">
      <span class="p-name fn">Johan Stromqvist</span>
    </dd><dd class="editor p-author h-card vcard">
      <span class="p-name fn">Kathleen McMahon</span>
    </dd><dd class="editor p-author h-card vcard">
      <span class="p-name fn">Kevin Powell</span>
    </dd><dd class="editor p-author h-card vcard">
      <span class="p-name fn">Louis Chenais</span>
    </dd><dd class="editor p-author h-card vcard">
      <span class="p-name fn">Matt Felten</span>
    </dd><dd class="editor p-author h-card vcard">
      <span class="p-name fn">Val Head</span>
    </dd>


        <dt>Feedback:</dt><dd>
          <a href="https://github.com/design-tokens/community-group/">GitHub design-tokens/community-group</a>
          (<a href="https://github.com/design-tokens/community-group/pulls/">pull requests</a>,
          <a href="https://github.com/design-tokens/community-group/issues/new/choose">new issue</a>,
          <a href="https://github.com/design-tokens/community-group/issues/">open issues</a>)
        </dd>
      </dl>


      <hr title="Separator for header">
    </div>

      <section id="abstract" class="introductory"><h2>Abstract</h2>
        <p>
          Design tokens are indivisible pieces of a design system such as colors,
          spacing, typography scale.
        </p>

        <p>
          Design tokens were created by the Salesforce design system team, and the
          name comes from them (<a href="https://twitter.com/jonnyl">Jon</a> &amp;
          <a href="https://twitter.com/jina">Jina</a>).
        </p>
      </section><section id="sotd" class="introductory"><h2>Status of This Document</h2><p>
        This specification was published by the
        <a href="https://www.w3.org/groups/cg/design-tokens">Design Tokens Community Group</a>. It is not a W3C Standard nor is it
        on the W3C Standards Track.

              Please note that under the
              <a href="https://www.w3.org/community/about/agreements/cla/">W3C Community Contributor License Agreement (CLA)</a>
                          there is a limited opt-out and other conditions apply.

        Learn more about
        <a href="https://www.w3.org/community/">W3C Community and Business Groups</a>.
      </p>
        <p>
          This section describes the status of this document at the time of its
          publication. Other documents may supersede this document. A list of
          current W3C Community Group reports and the latest revision of this
          report can be found in the W3C Community Group reports index at
          <a href="https://www.w3.org/community/reports/">https://www.w3.org/community/reports/</a>.
        </p>
        <p>
          This document was published by the DTCG as a
          <a href="https://www.w3.org/policies/process/#RecsWD">Working Draft</a>
          following the definitions provided by the W3C process. It is provided for
          discussion only and may change at any moment. Its publication here does not
          imply endorsement of its contents by W3C or the Design Tokens Community Group
          Membership. Don’t cite this document other than as work in progress.
        </p>
        <p>
          While not a W3C recommendation, this classification is intended to
          clarify that, after extensive consensus-building, this specification is
          intended for implementation.
        </p>
        <p>
          This specification is considered unstable, and should not be implemented.
        </p>
      <p>
      <a href="https://github.com/design-tokens/community-group/issues/">GitHub Issues</a> are preferred for
            discussion of this specification.

    </p></section><nav id="toc"><h2 class="introductory" id="table-of-contents">Table of Contents</h2><ol class="toc"><li class="tocline"><a class="tocxref" href="#abstract">Abstract</a></li><li class="tocline"><a class="tocxref" href="#modules"><bdi class="secno">1. </bdi>Modules</a></li><li class="tocline"><a class="tocxref" href="#resources"><bdi class="secno">2. </bdi>Resources</a></li><li class="tocline"><a class="tocxref" href="#acknowledgements"><bdi class="secno">A. </bdi>Acknowledgements</a></li></ol></nav>
      <section id="modules"><div class="header-wrapper"><h2 id="x1-modules"><bdi class="secno">1. </bdi>Modules</h2><a class="self-link" href="#modules" aria-label="Permalink for Section 1."></a></div>

        <p>The Design Tokens specification is composed of multiple modules:</p>
        <ul>
          <li>
            <a href="./format">Format</a>
          </li>
        </ul>
      </section>
      <section id="resources"><div class="header-wrapper"><h2 id="x2-resources"><bdi class="secno">2. </bdi>Resources</h2><a class="self-link" href="#resources" aria-label="Permalink for Section 2."></a></div>
  <ul>
  <li><a href="https://github.com/design-tokens/community-group/blob/main/CODE_OF_CONDUCT.md">Code of conduct</a></li>
  </ul>
  </section>

      <section class="appendix" id="acknowledgements"><div class="header-wrapper"><h2 id="a-acknowledgements"><bdi class="secno">A. </bdi>Acknowledgements</h2><a class="self-link" href="#acknowledgements" aria-label="Permalink for Appendix A."></a></div>

        <p>
          We'd also like to thank the following contributors:
          <span id="gh-contributors">Abhishek Warokar, Ale Muñoz, Benjamin Kindle, Bjørn Madsen, Chase McCoy, Dale Sande, Dominique Hazael-Massieux, Evan Lovely, Fabian Friedl, Guilherme Nagüeva, Ivan Maksimovic, Jina Anne, Jon Levine, Kaelig Deloumeau-Prigent, Kilian Valkhof, KLS, Miriam Suzanne, Namık Özgür Aydın, Rob Eisenberg, Robin, and Salem Cobalt</span>.
        </p>
      </section>


  <p role="navigation" id="back-to-top">
      <a href="#title"><abbr title="Back to Top">↑</abbr></a>
    </p><script id="respec-dfn-panel">(() => {
  // @ts-check
  if (document.respec) {
    document.respec.ready.then(setupPanel);
  } else {
    setupPanel();
  }

  function setupPanel() {
    const listener = panelListener();
    document.body.addEventListener("keydown", listener);
    document.body.addEventListener("click", listener);
  }

  function panelListener() {
    /** @type {HTMLElement} */
    let panel = null;
    return event => {
      const { target, type } = event;

      if (!(target instanceof HTMLElement)) return;

      // For keys, we only care about Enter key to activate the panel
      // otherwise it's activated via a click.
      if (type === "keydown" && event.key !== "Enter") return;

      const action = deriveAction(event);

      switch (action) {
        case "show": {
          hidePanel(panel);
          /** @type {HTMLElement} */
          const dfn = target.closest("dfn, .index-term");
          panel = document.getElementById(`dfn-panel-for-${dfn.id}`);
          const coords = deriveCoordinates(event);
          displayPanel(dfn, panel, coords);
          break;
        }
        case "dock": {
          panel.style.left = null;
          panel.style.top = null;
          panel.classList.add("docked");
          break;
        }
        case "hide": {
          hidePanel(panel);
          panel = null;
          break;
        }
      }
    };
  }

  /**
   * @param {MouseEvent|KeyboardEvent} event
   */
  function deriveCoordinates(event) {
    const target = /** @type HTMLElement */ (event.target);

    // We prevent synthetic AT clicks from putting
    // the dialog in a weird place. The AT events sometimes
    // lack coordinates, so they have clientX/Y = 0
    const rect = target.getBoundingClientRect();
    if (
      event instanceof MouseEvent &&
      event.clientX >= rect.left &&
      event.clientY >= rect.top
    ) {
      // The event probably happened inside the bounding rect...
      return { x: event.clientX, y: event.clientY };
    }

    // Offset to the middle of the element
    const x = rect.x + rect.width / 2;
    // Placed at the bottom of the element
    const y = rect.y + rect.height;
    return { x, y };
  }

  /**
   * @param {Event} event
   */
  function deriveAction(event) {
    const target = /** @type {HTMLElement} */ (event.target);
    const hitALink = !!target.closest("a");
    if (target.closest("dfn:not([data-cite]), .index-term")) {
      return hitALink ? "none" : "show";
    }
    if (target.closest(".dfn-panel")) {
      if (hitALink) {
        return target.classList.contains("self-link") ? "hide" : "dock";
      }
      const panel = target.closest(".dfn-panel");
      return panel.classList.contains("docked") ? "hide" : "none";
    }
    if (document.querySelector(".dfn-panel:not([hidden])")) {
      return "hide";
    }
    return "none";
  }

  /**
   * @param {HTMLElement} dfn
   * @param {HTMLElement} panel
   * @param {{ x: number, y: number }} clickPosition
   */
  function displayPanel(dfn, panel, { x, y }) {
    panel.hidden = false;
    // distance (px) between edge of panel and the pointing triangle (caret)
    const MARGIN = 20;

    const dfnRects = dfn.getClientRects();
    // Find the `top` offset when the `dfn` can be spread across multiple lines
    let closestTop = 0;
    let minDiff = Infinity;
    for (const rect of dfnRects) {
      const { top, bottom } = rect;
      const diffFromClickY = Math.abs((top + bottom) / 2 - y);
      if (diffFromClickY < minDiff) {
        minDiff = diffFromClickY;
        closestTop = top;
      }
    }

    const top = window.scrollY + closestTop + dfnRects[0].height;
    const left = x - MARGIN;
    panel.style.left = `${left}px`;
    panel.style.top = `${top}px`;

    // Find if the panel is flowing out of the window
    const panelRect = panel.getBoundingClientRect();
    const SCREEN_WIDTH = Math.min(window.innerWidth, window.screen.width);
    if (panelRect.right > SCREEN_WIDTH) {
      const newLeft = Math.max(MARGIN, x + MARGIN - panelRect.width);
      const newCaretOffset = left - newLeft;
      panel.style.left = `${newLeft}px`;
      /** @type {HTMLElement} */
      const caret = panel.querySelector(".caret");
      caret.style.left = `${newCaretOffset}px`;
    }

    // As it's a dialog, we trap focus.
    // TODO: when <dialog> becomes a implemented, we should really
    // use that.
    trapFocus(panel, dfn);
  }

  /**
   * @param {HTMLElement} panel
   * @param {HTMLElement} dfn
   * @returns
   */
  function trapFocus(panel, dfn) {
    /** @type NodeListOf<HTMLAnchorElement> elements */
    const anchors = panel.querySelectorAll("a[href]");
    // No need to trap focus
    if (!anchors.length) return;

    // Move focus to first anchor element
    const first = anchors.item(0);
    first.focus();

    const trapListener = createTrapListener(anchors, panel, dfn);
    panel.addEventListener("keydown", trapListener);

    // Hiding the panel releases the trap
    const mo = new MutationObserver(records => {
      const [record] = records;
      const target = /** @type HTMLElement */ (record.target);
      if (target.hidden) {
        panel.removeEventListener("keydown", trapListener);
        mo.disconnect();
      }
    });
    mo.observe(panel, { attributes: true, attributeFilter: ["hidden"] });
  }

  /**
   *
   * @param {NodeListOf<HTMLAnchorElement>} anchors
   * @param {HTMLElement} panel
   * @param {HTMLElement} dfn
   * @returns
   */
  function createTrapListener(anchors, panel, dfn) {
    const lastIndex = anchors.length - 1;
    let currentIndex = 0;
    return event => {
      switch (event.key) {
        // Hitting "Tab" traps us in a nice loop around elements.
        case "Tab": {
          event.preventDefault();
          currentIndex += event.shiftKey ? -1 : +1;
          if (currentIndex < 0) {
            currentIndex = lastIndex;
          } else if (currentIndex > lastIndex) {
            currentIndex = 0;
          }
          anchors.item(currentIndex).focus();
          break;
        }

        // Hitting "Enter" on an anchor releases the trap.
        case "Enter":
          hidePanel(panel);
          break;

        // Hitting "Escape" returns focus to dfn.
        case "Escape":
          hidePanel(panel);
          dfn.focus();
          return;
      }
    };
  }

  /** @param {HTMLElement} panel */
  function hidePanel(panel) {
    if (!panel) return;
    panel.hidden = true;
    panel.classList.remove("docked");
  }
  })()</script><script src="https://www.w3.org/scripts/TR/2021/fixup.js"></script></body></html>
